package com.campuscarbooking.api.service.impl;

import com.campuscarbooking.api.model.BusSchedule;
import com.campuscarbooking.api.repository.BusScheduleRepository;
import com.campuscarbooking.api.service.LocationValidationService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class LocationValidationServiceImpl implements LocationValidationService {

    private final BusScheduleRepository busScheduleRepository;

    @Value("${business.location.validation.radius:500}") // 默认500米范围内有效
    private int validRadiusInMeters;

    @Override
    public boolean validateLocation(Long scheduleId, Double latitude, Double longitude) {
        if (latitude == null || longitude == null) {
            return false;
        }

        BusSchedule schedule = busScheduleRepository.findById(scheduleId)
                .orElseThrow(() -> new IllegalArgumentException("Invalid schedule ID"));

        // 检查班车是否有位置信息
        if (schedule.getDepartureLatitude() == null || schedule.getDepartureLongitude() == null) {
            return false;
        }

        // 简化版距离计算 - 实际项目应使用更精确的地理空间计算
        double distanceToDeparture = calculateDistance(
            latitude, longitude,
            schedule.getDepartureLatitude(), schedule.getDepartureLongitude()
        );

        // 如果距离出发点在有效范围内则通过验证
        return distanceToDeparture <= validRadiusInMeters;
    }

    /**
     * 计算两点之间的距离(米)
     * 简化版Haversine公式实现
     */
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径(km)
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c * 1000; // 转换为米
    }
}
